/*
 * @Author: 肖思汗 
 * @Date: 2025-08-16 20:34:59 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2025-08-17 22:33:32
 */
import Taro from '@tarojs/taro';
import { DrawContext, FabricObject, Rect as FabricRect, TClassProperties } from 'fabric';
import { invertTransform } from '../myFabric/planeChange';
import cropBrContorls from './cropBrContorls';
import cropTlContorls from './cropTlContorls';
import cropTrContorls from './cropTrContorls';
import cropBlContorls from './cropBlContorls';
import cropTContorls from './cropTContorls';
import cropBContorls from './cropBContorls';
import cropLContorls from './cropLContorls';
import cropRContorls from './cropRContorls';

// 创建自定义矩形类，继承自 fabric.Rect
//@ts-ignore
export default class FabricMarkRect extends FabricRect {
    constructor(options: Partial<TClassProperties<FabricRect>> = {}) {
        // 设置默认选项
        const defaultOptions: Partial<TClassProperties<FabricRect>> = {
            stroke: '#ffffff', // 白色边框
            strokeWidth: 2,    // 边框宽度
            // fill: 'transparent', // 透明填充
            fill: '#ffffff', // 透明填充
            lockRotation: true,  // 禁止旋转
            selectable: false,   // 禁止选中
            hasControls: true,   // 显示控制器
            hasBorders: true,    // 显示边框
            lockScalingFlip: true, // 禁止翻转
            // 设置控制器样式
            cornerStyle: 'circle',
            cornerColor: '#3498db',
            cornerSize: 20,
            borderColor: '#ffffff'
        };

        // 合并用户选项和默认选项
        const mergedOptions = { ...defaultOptions, ...options };

        // 调用父类构造函数
        super(mergedOptions);

        // 添加等比缩放功能
        this.setControlsVisibility({
            mt: true,  // 上中
            mb: true,  // 下中
            ml: true,  // 左中
            mr: true,  // 右中
            tl: true,  // 左上
            tr: true,  // 右上
            bl: true,  // 左下
            br: true,  // 右下
            mtr: false // 旋转控制器 - 禁用
        });

        this.controls.br = cropBrContorls;
        this.controls.tl = cropTlContorls;
        this.controls.tr = cropTrContorls;
        this.controls.bl = cropBlContorls;
        this.controls.mt = cropTContorls;
        this.controls.mb = cropBContorls;
        this.controls.ml = cropLContorls;
        this.controls.mr = cropRContorls;

    }

    noScaleCache: boolean = false;

    // 添加返回类型注解 void
    drawObject(ctx: CanvasRenderingContext2D, forClipping: boolean | undefined, context: DrawContext): void {

        if (this.clipPath) {

            if ((this.width / this.height) > (this.clipPath.width / this.clipPath.height)) {

                if ((this.getScaledWidth() / this.getScaledHeight()) > (this.clipPath.width / this.clipPath.height)) {

                    const scaleY = this.height / this.clipPath.height;
                    const scaleX = scaleY * (this.scaleY / this.scaleX);
                    this.clipPath.set({
                        left: scaleX * this.clipPath.width! / -2,
                        top: scaleY * this.clipPath.height! / -2,
                        scaleX: scaleX,
                        scaleY: scaleY,
                    })
                } else {

                    const scaleX = this.width! / this.clipPath.width;
                    const scaleY = scaleX * (this.scaleX / this.scaleY);
                    this.clipPath.set({
                        left: scaleX * this.clipPath.width! / -2,
                        top: scaleY * this.clipPath.height! / -2,
                        scaleX: this.width! / this.clipPath.width,
                        scaleY: scaleY,
                    });
                }
            } else {

                if ((this.getScaledWidth() / this.getScaledHeight()) > (this.clipPath.width / this.clipPath.height)) {

                    const scaleY = this.height! / this.clipPath.height;
                    const scaleX = scaleY * (this.scaleY / this.scaleX);
                    this.clipPath.set({
                        left: scaleX * this.clipPath.width! / -2,
                        top: scaleY * this.clipPath.height! / -2,
                        scaleX: scaleX,
                        scaleY: scaleY,
                    });
                } else {

                    const scaleX = this.width! / this.clipPath.width;
                    const scaleY = scaleX * (this.scaleX / this.scaleY);
                    this.clipPath.set({
                        left: scaleX * this.clipPath.width! / -2,
                        top: scaleY * this.clipPath.height! / -2,
                        scaleX: scaleX,
                        scaleY: scaleY,
                    });
                }

            }
        }

        super.drawObject(ctx, forClipping, context);
    }

    _createCacheCanvas() {
        if (this.canvas) {
            this._cacheCanvas = Taro.createOffscreenCanvas({
                type: '2d',
                width: 1024,
                height: 1024,
            }) as unknown as HTMLCanvasElement;
            this._cacheContext = this._cacheCanvas.getContext('2d');
            this._updateCacheCanvas();
            // if canvas gets created, is empty, so dirty.
            this.dirty = true;
        }
    }

    createClipPathLayer(
        this: any,
        clipPath: FabricObject,
        context: DrawContext,
    ) {
        // taro 获取分辨率
        const canvas = Taro.createOffscreenCanvas({
            type: '2d',
            width: context.width,
            height: context.height,
        }) as unknown as HTMLCanvasElement;
        const ctx = canvas.getContext('2d')!;
        ctx.translate(context.cacheTranslationX, context.cacheTranslationY);
        ctx.scale(context.zoomX, context.zoomY);
        clipPath._cacheCanvas = canvas;
        context.parentClipPaths.forEach((prevClipPath) => {
            prevClipPath.transform(ctx);
        });
        context.parentClipPaths.push(clipPath);
        if (clipPath.absolutePositioned) {
            const m = invertTransform(this.calcTransformMatrix());
            ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
        }
        clipPath.transform(ctx);
        clipPath.drawObject(ctx, true, context);
        return canvas;
    }

}
